home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBASE102.ARJ / LSLOCK.C < prev    next >
Text File  |  1991-09-23  |  5KB  |  229 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)lslock.c    1.5 - 91/09/23" */
  5.  
  6. #include <ansi.h>
  7.  
  8. /* ansi headers */
  9. #include <errno.h>
  10.  
  11. /* library headers */
  12. #include <blkio.h>
  13.  
  14. /* local headers */
  15. #include "lseq_.h"
  16.  
  17. /* function declarations */
  18. #ifdef AC_PROTO
  19. static int resync(lseq_t *lsp);
  20. #else
  21. static int resync();
  22. #endif
  23.  
  24. /*man---------------------------------------------------------------------------
  25. NAME
  26.      lslock - lseq lock
  27.  
  28. SYNOPSIS
  29.      #include <lseq.h>
  30.  
  31.      int lslock(lsp, ltype)
  32.      lseq_t *lsp;
  33.      int ltype;
  34.  
  35. DESCRIPTION
  36.      The lslock function controls the lock status of an lseq.  The lsp
  37.      argument is an open lseq.  ltype indicates the target status of
  38.      the lock on the lseq.
  39.  
  40.      The lock types available are:
  41.  
  42.           LS_UNLCK - unlock lseq
  43.           LS_RDLCK - lock lseq for reading
  44.           LS_WRLCK - lock lseq for reading and writing
  45.           LS_RDLKW - lock lseq for reading (wait)
  46.           LS_WRLKW - lock lseq for reading and writing (wait)
  47.  
  48.      For the lock types which wait, lslock will not return until the
  49.      lock is available.  For the lock types which do not wait, if the
  50.      lock is unavailable because of a lock held by another process  a
  51.      value of -1 is returned and errno set to EAGAIN.
  52.  
  53.      When an lseq is unlocked, its cursor is set to null.
  54.  
  55.      lslock will fail if one or more of the following is true:
  56.  
  57.      [EAGAIN]       ltype is LS_RDLCK and lsp is already
  58.                     write locked by another process, or
  59.                     ltype is LS_WRLCK and lsp is already
  60.                     read or write locked by another process.
  61.      [EINVAL]       lsp is is not a valid lseq pointer.
  62.      [EINVAL]       ltype is not one of the valid lock
  63.                     types.
  64.      [LSECORRUPT]   lsp is corrupt.
  65.      [LSENOPEN]     lsp is not open.
  66.      [LSENOPEN]     ltype is LS_RDLCK or LS_RDLKW and lsp
  67.                     is not opened for reading or ltype is
  68.                     LS_WRLCK or LS_WRLKW and lsp is not open
  69.                     for writing.
  70.  
  71. SEE ALSO
  72.      lsgetlck.
  73.  
  74. DIAGNOSTICS
  75.      Upon successful completion, a value of 0 is returned.  Otherwise,
  76.      a value of -1 is returned, and errno set to indicate the error.
  77.  
  78. ------------------------------------------------------------------------------*/
  79. #ifdef AC_PROTO
  80. int lslock(lseq_t *lsp, int ltype)
  81. #else
  82. int lslock(lsp, ltype)
  83. lseq_t *lsp;
  84. int ltype;
  85. #endif
  86. {
  87.     int    bltype    = 0;    /* blkio lock type */
  88.  
  89.     /* validate arguments */
  90.     if (!ls_valid(lsp)) {
  91.         errno = EINVAL;
  92.         return -1;
  93.     }
  94.  
  95.     /* check if lseq not open */
  96.     if (!(lsp->flags & LSOPEN)) {
  97.         errno = LSENOPEN;
  98.         return -1;
  99.     }
  100.  
  101.     /* check if lseq not open for lock ltype */
  102.     switch (ltype) {
  103.     case LS_UNLCK:
  104.         lsp->clspos = NIL;    /* set cursor to null */
  105.         bltype = B_UNLCK;
  106.         break;
  107.     case LS_RDLCK:
  108.         if (!(lsp->flags & LSREAD)) {
  109.             errno = LSENOPEN;
  110.             return -1;
  111.         }
  112.         bltype = B_RDLCK;
  113.         break;
  114.     case LS_RDLKW:
  115.         if (!(lsp->flags & LSREAD)) {
  116.             errno = LSENOPEN;
  117.             return -1;
  118.         }
  119.         bltype = B_RDLKW;
  120.         break;
  121.     case LS_WRLCK:
  122.         if (!(lsp->flags & LSWRITE)) {
  123.             errno = LSENOPEN;
  124.             return -1;
  125.         }
  126.         bltype = B_WRLCK;
  127.         break;
  128.     case LS_WRLKW:
  129.         if (!(lsp->flags & LSWRITE)) {
  130.             errno = LSENOPEN;
  131.             return -1;
  132.         }
  133.         bltype = B_WRLKW;
  134.         break;
  135.     default:
  136.         errno = EINVAL;
  137.         return -1;
  138.         break;
  139.     }
  140.  
  141.     /* lock lseq file */
  142.     if (lockb(lsp->bp, bltype, (bpos_t)0, (bpos_t)0) == -1) {
  143.         if (errno != EAGAIN) LSEPRINT;
  144.         return -1;
  145.     }
  146.  
  147.     /* set status bits in lseq control structure */
  148.     switch (ltype) {
  149.     case LS_UNLCK:
  150.         lsp->flags &= ~LSLOCKS;
  151.         break;
  152.     case LS_RDLCK:
  153.     case LS_RDLKW:
  154.         /* if previously unlocked, re-sync with file */
  155.         if (!(lsp->flags & LSLOCKS)) {
  156.             if (resync(lsp) == -1) {
  157.                 LSEPRINT;
  158.                 return -1;
  159.             }
  160.         }
  161.         lsp->flags |= LSRDLCK;
  162.         lsp->flags &= ~LSWRLCK;
  163.         break;
  164.     case LS_WRLCK:
  165.     case LS_WRLKW:
  166.         /* if previously unlocked, re-sync with file */
  167.         if (!(lsp->flags & LSLOCKS)) {
  168.             if (resync(lsp) == -1) {
  169.                 LSEPRINT;
  170.                 return -1;
  171.             }
  172.         }
  173.         lsp->flags |= (LSRDLCK | LSWRLCK);
  174.         break;
  175.     default:
  176.         LSEPRINT;
  177.         errno = LSEPANIC;
  178.         return -1;
  179.         break;
  180.     }
  181.  
  182.     return 0;
  183. }
  184.  
  185. /* resync:  re-synchronize with file */
  186. #ifdef AC_PROTO
  187. static int resync(lseq_t *lsp)
  188. #else
  189. static int resync(lsp)
  190. lseq_t *lsp;
  191. #endif
  192. {
  193.     size_t    oldrecsize    = lsp->lshdr.recsize;    /* record size */
  194.     int    terrno        = 0;            /* tmp errno */
  195.  
  196.     /* read in header */
  197.     if (bgeth(lsp->bp, &lsp->lshdr) == -1) {
  198.         LSEPRINT;
  199.         return -1;
  200.     }
  201.  
  202.     /* check for corruption */
  203.     if (lsp->lshdr.flags & LSHMOD) {
  204.         errno = LSECORRUPT;
  205.         return -1;
  206.     }
  207.  
  208.     /* if first time locked, do setup */
  209.     if (oldrecsize == 0) {
  210.         /* allocate memory for lseq */
  211.         if (ls_alloc(lsp) == -1) {
  212.             LSEPRINT;
  213.             lsp->lshdr.recsize = 0;
  214.             return -1;
  215.         }
  216.         /* set up buffering */
  217.         if (bsetvbuf(lsp->bp, NULL, ls_blksize(lsp), LSBUFCNT) == -1) {
  218.             LSEPRINT;
  219.             terrno = errno;
  220.             ls_free(lsp);
  221.             lsp->lshdr.recsize = 0;
  222.             errno = terrno;
  223.             return -1;
  224.         }
  225.     }
  226.  
  227.     return 0;
  228. }
  229.